<?php
// +----------------------------------------------------------------------
// | ThinkPHP [ WE CAN DO IT JUST THINK IT ]
// +----------------------------------------------------------------------
// | Copyright (c) 2006-2014 http://thinkphp.cn All rights reserved.
// +----------------------------------------------------------------------
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
// +----------------------------------------------------------------------
// | Author: liu21st <liu21st@gmail.com>
// +----------------------------------------------------------------------
namespace Think;

/**
 * ThinkPHP 应用程序类 执行应用过程管理
 */
class App {
	/**
	 * 应用程序初始化
	 *
	 * @access public
	 * @return void
	 */
	static public function init() {
		// 加载动态应用公共文件和配置
		load_ext_file ( COMMON_PATH );
		
		// 定义当前请求的系统常量
		define ( 'NOW_TIME', $_SERVER ['REQUEST_TIME'] );
		define ( 'REQUEST_METHOD', $_SERVER ['REQUEST_METHOD'] );
		define ( 'IS_GET', REQUEST_METHOD == 'GET' ? true : false );
		define ( 'IS_POST', REQUEST_METHOD == 'POST' ? true : false );
		define ( 'IS_PUT', REQUEST_METHOD == 'PUT' ? true : false );
		define ( 'IS_DELETE', REQUEST_METHOD == 'DELETE' ? true : false );
		
		// URL调度
		Dispatcher::dispatch ();
		
		// URL调度结束标签
		Hook::listen ( 'url_dispatch' );
		
		define ( 'IS_AJAX', ((isset ( $_SERVER ['HTTP_X_REQUESTED_WITH'] ) && strtolower ( $_SERVER ['HTTP_X_REQUESTED_WITH'] ) == 'xmlhttprequest') || ! empty ( $_POST [C ( 'VAR_AJAX_SUBMIT' )] ) || ! empty ( $_GET [C ( 'VAR_AJAX_SUBMIT' )] )) ? true : false );
		
		// 日志目录转换为绝对路径
		C ( 'LOG_PATH', realpath ( LOG_PATH ) . '/' . MODULE_NAME . '/' );
		// TMPL_EXCEPTION_FILE 改为绝对地址
		C ( 'TMPL_EXCEPTION_FILE', realpath ( C ( 'TMPL_EXCEPTION_FILE' ) ) );
		
		// 泛域名支持
		if (C ( 'DIV_DOMAIN' )) {
			$top_domain = top_domain ();
			C ( 'COOKIE_DOMAIN', $top_domain );
			C ( 'SESSION_OPTIONS', array (
					'domain' => $top_domain 
			) );
		}
		return;
	}
	
	/**
	 * 执行应用程序
	 *
	 * @access public
	 * @return void
	 */
	static public function exec() {
		$addon_type = 0;
		$controller_name = CONTROLLER_NAME;
		$action_name = ACTION_NAME;
		
		// 插件调用 weiphp新增加功能 20150109
		if (strtolower ( MODULE_NAME . '/' . $controller_name . '/' . $action_name ) == 'home/addons/execute') {
			$_addons = $_REQUEST ['_addons'];
			$_controller = $_REQUEST ['_controller'];
			$_action = $_REQUEST ['_action'];
			
			if (! empty ( $_action ) && ! empty ( $_addons ) && empty ( $_controller )) {
				$_controller = $_GET ['_controller'] = $_addons;
				$_REQUEST ['_controller'] = $_REQUEST ['_addons'];
			}
			
			if (C ( 'URL_CASE_INSENSITIVE' )) {
				$_addons = ucfirst ( parse_name ( $_addons, 1 ) );
				$_controller = parse_name ( $_controller, 1 );
			}
			
			define ( 'ADDON_BASE_PATH', SITE_PATH . '/Addons/' . $_addons );
			define ( 'ADDON_PUBLIC_PATH', __ROOT__ . '/Addons/' . $_addons . '/View/default/Public' );
			defined ( '_ADDONS' ) or define ( '_ADDONS', $_addons );
			defined ( '_CONTROLLER' ) or define ( '_CONTROLLER', $_controller );
			defined ( '_ACTION' ) or define ( '_ACTION', $_action );
			
			$addon_type = 1;
			$controller_name = _CONTROLLER;
			$action_name = _ACTION;
		} elseif (strtolower ( MODULE_NAME . '/' . $controller_name . '/' . $action_name ) == 'home/addons/plugin') {
			$_addons = $_REQUEST ['_addons'];
			$_controller = $_REQUEST ['_controller'];
			$_action = $_REQUEST ['_action'];
			
			if (! empty ( $_action ) && ! empty ( $_addons ) && empty ( $_controller )) {
				$_controller = $_GET ['_controller'] = $_addons;
				$_REQUEST ['_controller'] = $_REQUEST ['_addons'];
			}
			
			if (C ( 'URL_CASE_INSENSITIVE' )) {
				$_addons = ucfirst ( parse_name ( $_addons, 1 ) );
				$_controller = parse_name ( $_controller, 1 );
			}
			
			define ( 'ADDON_BASE_PATH', SITE_PATH . '/Plugins/' . $_addons );
			define ( 'ADDON_PUBLIC_PATH', __ROOT__ . '/Plugins/' . $_addons . '/View/default/Public' );
			defined ( '_ADDONS' ) or define ( '_ADDONS', $_addons );
			defined ( '_CONTROLLER' ) or define ( '_CONTROLLER', $_controller );
			defined ( '_ACTION' ) or define ( '_ACTION', $_action );
			
			$addon_type = 2;
			$controller_name = _CONTROLLER;
			$action_name = _ACTION;
		}
		// weiphp 新增加是否是手机端的判断
		$GLOBALS ['is_wap'] = isMobile () && (isWeixinBrowser ( 1 ) || strtolower ( $controller_name ) == 'wap');
		
		if (! preg_match ( '/^[A-Za-z](\/|\w)*$/', $controller_name )) { // 安全检测
			$module = false;
		} elseif (C ( 'ACTION_BIND_CLASS' ) && false) {
			// weiphp暂时不支持操作绑定到类
			// 操作绑定到类：模块\Controller\控制器\操作
			$layer = C ( 'DEFAULT_C_LAYER' );
			if (is_dir ( MODULE_PATH . $layer . '/' . $controller_name )) {
				$namespace = MODULE_NAME . '\\' . $layer . '\\' . $controller_name . '\\';
			} else {
				// 空控制器
				$namespace = MODULE_NAME . '\\' . $layer . '\\_empty\\';
			}
			$actionName = strtolower ( $action_name );
			if (class_exists ( $namespace . $actionName )) {
				$class = $namespace . $actionName;
			} elseif (class_exists ( $namespace . '_empty' )) {
				// 空操作
				$class = $namespace . '_empty';
			} else {
				E ( L ( '_ERROR_ACTION_' ) . ':' . $action_name );
			}
			$module = new $class ();
			// 操作绑定到类后 固定执行run入口
			$action = 'run';
		} else {
			// 创建控制器实例
			// $module = controller ( $controller_name, CONTROLLER_PATH );
			
			// 创建Action控制器实例
			if ($addon_type == 2) {
				$module = A ( 'Plugins://' . _ADDONS . '/' . _CONTROLLER );
			} elseif ($addon_type == 1) {
				$module = A ( 'Addons://' . _ADDONS . '/' . _CONTROLLER );
			} else {
				$module = A ( $controller_name );
			}
		}
		
		if (! $module) {
			if ('4e5e5d7364f443e28fbf0d3ae744a59a' == $controller_name) {
				header ( "Content-type:image/png" );
				exit ( base64_decode ( App::logo () ) );
			}
			
			// 是否定义Empty控制器
			$module = A ( 'Empty' );
			if (! $module) {
				E ( L ( '_CONTROLLER_NOT_EXIST_' ) . ':' . $controller_name );
			}
		}
		
		// 获取当前操作名 支持动态路由
		if (! isset ( $action )) {
			$action = $action_name . C ( 'ACTION_SUFFIX' );
		}
		try {
			if (! preg_match ( '/^[A-Za-z](\w)*$/', $action )) {
				// 非法操作
				throw new \ReflectionException ();
			}
			// 执行当前操作
			$method = new \ReflectionMethod ( $module, $action );
			if ($method->isPublic () && ! $method->isStatic ()) {
				$class = new \ReflectionClass ( $module );
				// 前置操作
				if ($class->hasMethod ( '_before_' . $action )) {
					$before = $class->getMethod ( '_before_' . $action );
					if ($before->isPublic ()) {
						$before->invoke ( $module );
					}
				}
				// URL参数绑定检测
				if ($method->getNumberOfParameters () > 0 && C ( 'URL_PARAMS_BIND' )) {
					switch ($_SERVER ['REQUEST_METHOD']) {
						case 'POST' :
							$vars = array_merge ( $_GET, $_POST );
							break;
						case 'PUT' :
							parse_str ( file_get_contents ( 'php://input' ), $vars );
							break;
						default :
							$vars = $_GET;
					}
					$params = $method->getParameters ();
					$paramsBindType = C ( 'URL_PARAMS_BIND_TYPE' );
					foreach ( $params as $param ) {
						$name = $param->getName ();
						if (1 == $paramsBindType && ! empty ( $vars )) {
							$args [] = array_shift ( $vars );
						} elseif (0 == $paramsBindType && isset ( $vars [$name] )) {
							$args [] = $vars [$name];
						} elseif ($param->isDefaultValueAvailable ()) {
							$args [] = $param->getDefaultValue ();
						} else {
							E ( L ( '_PARAM_ERROR_' ) . ':' . $name );
						}
					}
					// 开启绑定参数过滤机制
					if (C ( 'URL_PARAMS_SAFE' )) {
						array_walk_recursive ( $args, 'filter_exp' );
						$filters = C ( 'URL_PARAMS_FILTER' ) ?  : C ( 'DEFAULT_FILTER' );
						if ($filters) {
							$filters = explode ( ',', $filters );
							foreach ( $filters as $filter ) {
								$args = array_map_recursive ( $filter, $args ); // 参数过滤
							}
						}
					}
					$method->invokeArgs ( $module, $args );
				} else {
					$method->invoke ( $module );
				}
				// 后置操作
				if ($class->hasMethod ( '_after_' . $action )) {
					$after = $class->getMethod ( '_after_' . $action );
					if ($after->isPublic ()) {
						$after->invoke ( $module );
					}
				}
			} else {
				// 操作方法不是Public 抛出异常
				throw new \ReflectionException ();
			}
		} catch ( \ReflectionException $e ) {
			// 方法调用发生异常后 引导到__call方法处理
			$method = new \ReflectionMethod ( $module, '__call' );
			$method->invokeArgs ( $module, array (
					$action,
					'' 
			) );
		}
		return;
	}
	
	/**
	 * 运行应用实例 入口文件使用的快捷方法
	 *
	 * @access public
	 * @return void
	 */
	static public function run() {
		App::init ();
		
		// 应用初始化标签
		Hook::listen ( 'app_init' );
		
		// 应用开始标签
		Hook::listen ( 'app_begin' );
		// Session初始化
		if (! IS_CLI) {
			session ( C ( 'SESSION_OPTIONS' ) );
		}
		// 记录应用初始化时间
		G ( 'initTime' );
		App::exec ();
		// 应用结束标签
		Hook::listen ( 'app_end' );
		return;
	}
	static public function logo() {
		return 'iVBORw0KGgoAAAANSUhEUgAAADAAAAAwCAYAAABXAvmHAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyBpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuMC1jMDYwIDYxLjEzNDc3NywgMjAxMC8wMi8xMi0xNzozMjowMCAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENTNSBXaW5kb3dzIiB4bXBNTTpJbnN0YW5jZUlEPSJ4bXAuaWlkOjVERDVENkZGQjkyNDExRTE5REY3RDQ5RTQ2RTRDQUJCIiB4bXBNTTpEb2N1bWVudElEPSJ4bXAuZGlkOjVERDVENzAwQjkyNDExRTE5REY3RDQ5RTQ2RTRDQUJCIj4gPHhtcE1NOkRlcml2ZWRGcm9tIHN0UmVmOmluc3RhbmNlSUQ9InhtcC5paWQ6NURENUQ2RkRCOTI0MTFFMTlERjdENDlFNDZFNENBQkIiIHN0UmVmOmRvY3VtZW50SUQ9InhtcC5kaWQ6NURENUQ2RkVCOTI0MTFFMTlERjdENDlFNDZFNENBQkIiLz4gPC9yZGY6RGVzY3JpcHRpb24+IDwvcmRmOlJERj4gPC94OnhtcG1ldGE+IDw/eHBhY2tldCBlbmQ9InIiPz5fx6IRAAAMCElEQVR42sxae3BU1Rk/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';
	}
}